package com.syf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syf.domain.SysUser;
import com.syf.domain.SysUserRole;
import com.syf.mapper.SysUserMapper;
import com.syf.service.SysUserRoleService;
import com.syf.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
*
*
*@author 苏耀奋
*@create 2021-07-11 12:11
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {


    @Autowired
    private SysUserRoleService sysUserRoleService ;

    /**
     * 分页查询员工
     *
     * @param page     分页参数
     * @param mobile   员工的手机号
     * @param fullname 员工的全名称
     * @return
     */
    @Override
    public Page<SysUser> findByPage(Page<SysUser> page, String mobile, String fullname) {
        //分页条件查询
        Page<SysUser> pageData = page(page, new LambdaQueryWrapper<SysUser>()
                .like(!StringUtils.isEmpty(mobile), SysUser::getMobile, mobile)
                .like(!StringUtils.isEmpty(fullname), SysUser::getFullname, fullname)
        );
        //点击编辑 -> 角色回显【查询所有用户的所有角色】
        List<SysUser> records = pageData.getRecords();
        if(!CollectionUtils.isEmpty(records)){
            for(SysUser record: records){
                //1.根据用户id 查询 该用户的所有角色
                List<SysUserRole> userRoles = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, record.getId()));
                if(!CollectionUtils.isEmpty(userRoles)){
                    record.setRole_strings( //将所有角色id -> toString -> 用","收集起来
                            userRoles.stream().
                                    map(sysUserRole -> sysUserRole.getRoleId().toString())
                                    .collect(Collectors.joining(",")));
                }
                //2.将加密密码 -> 正常密码【不可逆转】
            }
        }


        return pageData;
    }

    /**
     * 新增员工：
     *      早期使用md5对密码进行编码，每次算出的md5值都一样，这样非常不安全，Spring Security推荐使用 BCryptPasswordEncoder对
     *      密码加随机盐，每次的Hash值都不一样，安全性高
     * @param sysUser
     * @return
     */
    @Override
    @Transactional
    public boolean addUser(SysUser sysUser) {
        // 1 用户的密码进行加密【前端还需要一个将加密密码 -> 正常密码 -> 进行显示】
        String password = sysUser.getPassword();
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(password); // 加密密码
        /*boolean f = bCryptPasswordEncoder.matches("admin",encode); //判断"admin" 与 admin加密密码是否相同
        System.out.println(f); //每次输出的hashPass 都不一样，但是最终的f都为 true,即匹配成功*/

        sysUser.setPassword(encode); // 设置密码
        // 2.员工新增
        boolean save = super.save(sysUser);

        // 3.用户的角色Ids【为用户分配角色】
        String role_strings = sysUser.getRole_strings();
        if(save){
            // 4.给用户批量新增角色数据
            if(!StringUtils.isEmpty(role_strings)){
                String[] roleIds = role_strings.split(",");
                List<SysUserRole> sysUserRoleList = new ArrayList<>(roleIds.length) ; //多个角色
                for (String roleId : roleIds) {
                    SysUserRole sysUserRole = new SysUserRole();
                    sysUserRole.setRoleId(Long.valueOf(roleId));
                    sysUserRole.setUserId(sysUser.getId());
                    sysUserRoleList.add(sysUserRole) ;
                }
                sysUserRoleService.saveBatch(sysUserRoleList) ;
            }
        }
        return save;
    }

    /**
     * 修改员工信息:
     *      1.加密后的密码直接修改为 新密码
     *      2.修改员工信息后，先批量删除 之前角色，再批量添加新的角色
     *
     * @param sysUser
     * @return
     */
    @Transactional
    @Override
    public boolean updataUser(SysUser sysUser) { //员工信息(包含用户id,多个角色ids)
        // 1 用户的密码【还需要】
        String password = sysUser.getPassword();
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(password); // 加密密码
        sysUser.setPassword(encode); // 设置密码
        // 2.用户的角色Ids
        String role_strings = sysUser.getRole_strings();
        //3.修改员工
        boolean update = super.updateById(sysUser);

        if(update){
            //批量删除该用户旧角色
            boolean remove = sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, sysUser.getId()));

            // 5..给用户批量新增角色数据
            if(!StringUtils.isEmpty(role_strings)){
                String[] roleIds = role_strings.split(",");
                List<SysUserRole> sysUserRoleList = new ArrayList<>(roleIds.length) ; //多个角色
                for (String roleId : roleIds) {
                    SysUserRole sysUserRole = new SysUserRole();
                    sysUserRole.setRoleId(Long.valueOf(roleId));
                    sysUserRole.setUserId(sysUser.getId());
                    sysUserRoleList.add(sysUserRole) ;
                }
                sysUserRoleService.saveBatch(sysUserRoleList) ;
            }
        }
        return update;
    }

    /**
     * 批量删除员工用户、及用户具有的角色：
     *
     * @param idList
     * @return
     */
    @Override
    @Transactional
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        boolean b = super.removeByIds(idList);
        sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId,idList)) ;
        return b;
    }
}
